# -*- coding: utf-8 -*-
from __future__ import division
import numpy as np
from load_data.loadnpz import sliding_window
from load_data.loadnpz import loadnpz
from processor import bandpass_filter, CARFilter, csp_train, csp_spatial_filter, \
    MIBIFTrain, MIBIFSelect, classifier_train, classifier_predict


def load_npzdata(Path):
    data_x_gather, data_y_gather = None, None
    file_num = len(Path)
    for i in range(file_num):
        data_x, data_y = loadnpz(Path[i])
        if i == 0:
            data_x_gather = data_x
            data_y_gather = data_y
        else:
            data_x_gather = np.concatenate((data_x_gather, data_x), axis=2)
            data_y_gather = np.concatenate((data_y_gather, data_y), axis=0)
    return data_x_gather, data_y_gather


def gather_feature(data_x):
    # data_x: trial×filter×feature or filter×feature
    if len(data_x.shape) == 3:
        feature = data_x.reshape(data_x.shape[0], data_x.shape[1]*data_x.shape[2])
    else:
        feature = data_x.reshape(1, data_x.shape[0]*data_x.shape[1])
    return feature


def pipeline_on_epoch(train_x, train_y, test_x, test_y, iter=10):
    """
    对trial数据滑窗，计算epoch的分类准确度

    train_x/test_x: ndarray T×N×L 或单个trial T×N
        T: 采样点数（从 768 Start_Of_Trial 到 800 End_Of_Trial） N: 通道数  L: 训练数据 trial 总数
    train_y/test_y: shape (n_samples,)
        L 个 trial 对应的标签
    iter: 迭代次数
    ----------
    accuracy_list: (iter,) 分类准确度
    """
    filter_bank = False
    accuracy_list = []
    while True:
        # —— pre-processing ——
        train_data = CARFilter(train_x)  # CAR 滤波
        train_data = bandpass_filter(train_data, Fs=500, filter_low=4, filter_high=40, filter_bank=filter_bank, filter_num=1)
        test_data = CARFilter(test_x)
        test_data = bandpass_filter(test_data, Fs=500, filter_low=4, filter_high=40, filter_bank=filter_bank, filter_num=1)
        print('—— training ——')
        train_data, train_label = sliding_window(train_data, train_y, filter_bank=filter_bank)  # 滑窗
        csp_proj_matrix = csp_train(train_data, train_label, m=3, filter_bank=filter_bank)
        feature = csp_spatial_filter(train_data, csp_proj_matrix, filter_bank=filter_bank)
        if filter_bank:
            feature_set = MIBIFTrain(feature, train_label, select_feature_num=4)
            feature = MIBIFSelect(feature, feature_set)
        #     feature = gather_feature(feature)
        classifier_model = classifier_train(feature, train_label, classifier_type='lda', filter_bank=False)
        print('—— testing ——')
        test_data, test_label = sliding_window(test_data, test_y, filter_bank=filter_bank)
        feature = csp_spatial_filter(test_data, csp_proj_matrix, filter_bank=filter_bank)  # CSP 空间投影
        if filter_bank:
            feature = MIBIFSelect(feature, feature_set)
            # feature = gather_feature(feature)
        predict = classifier_predict(classifier_model, feature, filter_bank=False)  # 分类
        # —— analysis ——
        right_sum = np.sum(predict == test_label)
        acc = right_sum / len(test_label)
        print('acc:', acc)
        accuracy_list.append(acc)
        iter = iter - 1
        if iter == 0:
            break
    return accuracy_list


if __name__ == '__main__':
    trainPath = [r'D:\Myfiles\data_set\zhu_jun_jie\zhu_jun_jie_20190227\acquireNSsignal_2019_02_27_17_03_07.npz',
                 # r'D:\Myfiles\PythonProjects\signal\ZJJ\0504\acquireNSsignal_2018_05_04_14_06_28.npz'
                 ]
    testPath = [r'D:\Myfiles\data_set\zhu_jun_jie\zhu_jun_jie_20190227\onlineNSsignal_2019_02_27_17_10_00.npz',
                # r'D:\Myfiles\PythonProjects\signal\ZJJ\0504\onlineNSsignal_2018_05_04_14_30_41.npz'
                ]
    test_x, test_y = load_npzdata(testPath)
    train_x, train_y = load_npzdata(trainPath)
    accuracy_list = pipeline_on_epoch(train_x, train_y, test_x, test_y, iter=1)  # csp0.64 fbcsp0.54
    Accuracy = np.mean(accuracy_list)
    print('acc:', accuracy_list)
    print(Accuracy)
